clDecodeMode::clDecodeMode(){
	Value	= LEDDecodeALL;
	Address = LEDRegDecodeModeAddr;
}

clShutdownMode::clShutdownMode(){
	Value	= LEDShutdownOff;
	Address = LEDRegShutdownModeAddr;
}

clScanCount::clScanCount(){
	Value	= LEDScanCount4;
	Address = LEDRegScanCountAddr;
}

clIntensity::clIntensity(){
	Value	= LEDIntensityHighMax;
	Address = LEDRegIntensityAddr;
}

clTest::clTest(){
	Value	= LEDTestOff;
	Address = LEDRegTestAddr;
}

void clLED7221::Connect(bool val){
	clSPIDeviceWReg::Connect();
	SegmentsDisplay();
}

void clLED7221::DisConnect(){
	clSPIDeviceWReg::DisConnect();
}

clLED7221::clLED7221(clSPI *lSPI, PortStruct lPort, ePins lCSPin): clSPIDeviceWReg(lSPI, lPort, lCSPin){
	LeaderZeroShow		= false;
	Alignment			= AligmentRight;
	
	unsigned char SegmentIndex;
	
	for (SegmentIndex = 0; SegmentIndex < SegmentCount; SegmentIndex++)
	{
		Segments[SegmentIndex].Address	= LEDSegmentsAddr[SegmentIndex];
		Segments[SegmentIndex].Value	= 0;
		Segments[SegmentIndex].pDevice	= this;
	};
	
	RegsInit();
	RegsSend();
	SegmentsDisplay();
}

void clLEDSegment::SetValue(unsigned char lVal){
	clScanCount	*lScanCont;

	lScanCont	= &(((clLED7221 *) pDevice)->LEDRegisters.ScanCount);
	if (lScanCont->Value < (Address - 1)){
		lScanCont->SetValue(Address - 1);
	}
	
	clReg8WSPI::SetValue(lVal);
}

const unsigned char clLED7221::SegmentCount = LEDSegmentCount;

void clLED7221::SegmentsDisplay(){
	unsigned char SegmentIndex;
	
	for (SegmentIndex = 0; SegmentIndex < SegmentCount; SegmentIndex++)
	{
		Segments[SegmentIndex].SendToSPI();
	}
}

void clLED7221::RegsInit(){
	LEDRegisters.DecodeMode.pDevice     = this;
	LEDRegisters.Intensity.pDevice      = this;
	LEDRegisters.ScanCount.pDevice      = this;
	LEDRegisters.ShutdownMode.pDevice   = this;
	LEDRegisters.Test.pDevice           = this;
}

void clLED7221::RegsSend(void){
	LEDRegisters.DecodeMode.SendToSPI();
	LEDRegisters.Intensity.SendToSPI();
	LEDRegisters.ScanCount.SendToSPI();
	LEDRegisters.ShutdownMode.SendToSPI();
	LEDRegisters.Test.SendToSPI();
};

void clLED7221::SegmentValueOverflow(){
#warning "Segment value overflow not implemented!"	
}

void clLED7221::Print(int lVal){
	signed char	LEDIndex, Degree = 1;// ScanLimit;
	int			tVal, Rate;
	bool		ZeroShow	= LeaderZeroShow;
	
	tVal	= lVal;
	while (tVal	/= 10){Degree++;}

	if (Degree > LEDSegmentCount){
		SegmentValueOverflow();
		return;
	}

	LEDIndex	= (Alignment == AligmentLeft) ? (Degree - LEDSegmentCount): 0;
	
	for (Degree = LEDSegmentCount; Degree > 0; Degree--){
		if (LEDIndex >= 0){
			Rate	= Degree;
			Rate	= MyPow(10, (--Rate));
			tVal	= lVal/Rate;
			if (tVal == 0){
				tVal	= ((tVal == 0) && (ZeroShow)) ? 0: 0x0f;
			}
			else{
				ZeroShow	= true;
			};
			Segments[LEDIndex].SetValue(tVal);
			tVal	= lVal/Rate;
			lVal	-= int(tVal)*Rate;
		}
		LEDIndex++;
	}

	while (LEDIndex < LEDSegmentCount){
			Segments[LEDIndex].SetValue(0x0f);
			LEDIndex++;
	}
}